package netty.demo_03_HTTP;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import sun.nio.cs.ext.MS874;

import java.net.URI;

/**
 * 快速入门实例-HTTP服务
 * 服务端处理器，用于接收和发送消息
 *
 * @author chenyuan
 * @date 2020/11/7 15:25
 */
/*
    1. SimpleChannelInboundHandler 是之前使用的 ChannelInboundHandlerAdapter 的子类
    2. HttpObject 这个类型表示， 客户端、服务端 相互通信的数据需要被封装成什么类型
 */
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
	/**
	 * 读取客户端数据
	 *
	 * @param channelHandlerContext 上下文
	 * @param httpObject            传递过来的消息
	 * @throws Exception
	 */
	@Override
	protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
		// 判断 httpObject 是不是一个 HttpRequest 请求
		if (httpObject instanceof HttpRequest) {
			System.out.println("httpObject 的类型 ：" + httpObject.getClass());
			System.out.println("客户端的地址 ： " + channelHandlerContext.channel().remoteAddress());

			//== 对特定资源进行过滤 =======
			// 获取请求的 URI
			HttpRequest httpRequest = (HttpRequest) httpObject;
			URI uri = new URI(httpRequest.uri());
			// 判断请求路径为 /favicon.ico，就不做处理
			if ("/favicon.ico".equals(uri.getPath())) {
				System.out.println("请求了 图标 资源，不做响应");
				return;
			}
			//==================

			// 回复信息给浏览器,需要把数据封装成 HttpObject 类型
			// 创建一个 ButeBuf
			ByteBuf byteBuf = Unpooled.copiedBuffer("Hello，我是服务器", CharsetUtil.UTF_8);
			// 构建一个 Http 的响应，即 httpResponse  ;  后面的三个参数 ：（Http 协议的版本， Http 的状态码， 需要传输的内容）
			FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, byteBuf);
			// 设置文本的类型,及字符编码
			response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=utf-8");
			// 文本的长度
			response.headers().set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
			// 将构建好的 response 返回
			channelHandlerContext.writeAndFlush(response);
		}
	}
}
